package com.dukk.gis.tools;

import com.mapbox.geojson.gson.GeometryGeoJson;
import com.mapbox.turf.TurfMeasurement;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.Point;
import org.locationtech.spatial4j.distance.DistanceUtils;
import java.math.BigDecimal;

/**
 * 距离相关计算工具类
 */
public class DistanceTool {
    static double EARTH_MEAN_RADIUS_KM = DistanceUtils.EARTH_MEAN_RADIUS_KM; //地球平均半径

    /**
     * 距离(CM)转换为度
     * @param cm
     * @return
     */
    public static double cmToDegree(double cm){
        //1KM大约等于多少度
        BigDecimal bigDecimalCm = new BigDecimal(cm);
        BigDecimal bigDecimalKM = new BigDecimal(100000);
        double dist = bigDecimalCm.divide(bigDecimalKM).doubleValue();
        double kmToDegree = DistanceUtils.dist2Degrees(dist, EARTH_MEAN_RADIUS_KM);
        return kmToDegree;
    }

    /**
     * 距离(KM)转换为度
     * @param km
     * @return
     */
    public static double kmToDegree(double km){
        return cmToDegree(km*100000);
    }

    /**
     * 度转换为距离(单位KM)
     * @param degree
     * @return
     */
    public static double degreeToKm(double degree){
        return DistanceUtils.degrees2Dist(degree, EARTH_MEAN_RADIUS_KM);
    }

    /**
     * 度转换为距离(单位M)
     * @param degree
     * @return
     */
    public static double degreeToM(double degree){
        return DistanceUtils.degrees2Dist(degree, EARTH_MEAN_RADIUS_KM) * 1000;
    }

    /**
     * °转换为厘米
     * @param degree
     * @return
     */
    public static double degreeToCm(double degree){
        return DistanceUtils.degrees2Dist(degree, EARTH_MEAN_RADIUS_KM) * 1000 * 100;
    }

    /**
     * 获取几何距离单位(米)
     * @param geometry
     * @return
     */
    public static double getLengthM(Geometry geometry){
        return degreeToM(geometry.getLength());
    }

    /**
     * 获取几何距离单位(千米)
     * @param geometry
     * @return
     */
    public static double getLengthKM(Geometry geometry){
        return degreeToKm(geometry.getLength());
    }


    /**
     * 获取两点的距离
     * @param coordinate0
     * @param coordinate1
     * @return
     */
    public static double p2pLenDegrees(Coordinate coordinate0, Coordinate coordinate1){
        return coordinate0.distance(coordinate1);
    }

    /**
     * 获取两点距离(KM)
     * @param coordinate0
     * @param coordinate1
     * @return
     */
    public static double p2pLenKm(Coordinate coordinate0, Coordinate coordinate1){
        return degreeToKm(p2pLenDegrees(coordinate0, coordinate1));
    }

    /**
     * 获取两点距离(M)
     * @param coordinate0
     * @param coordinate1
     * @return
     */
    public static double p2pLenM(Coordinate coordinate0, Coordinate coordinate1){
        return degreeToM(p2pLenDegrees(coordinate0, coordinate1));
    }

    /**
     * 点到线的最近距离
     * @param point
     * @param lineString
     * @return
     */
    public static double p2LineDegrees(Point point, LineString lineString){
        return point.distance(lineString);
    }

    /**
     * 点到线的最近距离(KM)
     * @param point
     * @param lineString
     * @return
     */
    public static double p2LineKM(Point point, LineString lineString){
        return degreeToKm(point.distance(lineString));
    }

    /**
     * 点到线的最近距离(M)
     * @param point
     * @param lineString
     * @return
     */
    public static double p2LineM(Point point, LineString lineString){
        return degreeToM(point.distance(lineString));
    }


    /**
     * 通过turf计算距离 椭球距离
     * @param lineString
     * @param unit 单位turfConstants
     * @return
     */
    public static double distanceByTurf(LineString lineString, String unit){
        String jsonString = GeoJsonTool.toJSONString(lineString);
        return TurfMeasurement.length((com.mapbox.geojson.LineString) GeometryGeoJson.fromJson(jsonString), unit);
    }

}
